package com.cloud.ebookreader.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;

import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileReadChannel;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.files.GSFileOptions.GSFileOptionsBuilder;
import com.google.appengine.api.files.LockException;

public class GSFileUtils {
	public static String EBOOK_READER_BUCKET_NAME = "cloudebookreader";
	private static int BUFFER = 2048;
	
	/**
	 * Write a file to Google Cloud Storage
	 * 
	 * @param bucketName
	 * @param fileToWrite
	 * @return
	 * @throws IOException
	 */
	public static boolean writeFileToGoogleStorage(String bucketName, File fileToWrite, String mime) throws IOException {
		
		ByteBuffer buffer = ByteBuffer.allocate(BUFFER);
		
		FileService fileService = FileServiceFactory.getFileService();

		GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder()
				.setBucket(bucketName).setKey(fileToWrite.getName())
				.setMimeType(mime).setAcl("public_read");
				//.addUserMetadata("myfield1", "my field 1 value");

		AppEngineFile writableFile = fileService.createNewGSFile(optionsBuilder
				.build());

		// open a channel to write to it
		boolean lock = false;
		FileWriteChannel writeChannel = fileService.openWriteChannel(
				writableFile, lock);
		// Different standard Java ways of writing to the channel
		// are possible. Here we use a PrintWriter:
		final FileInputStream fis = new FileInputStream(fileToWrite);
		FileChannel fisChannel = fis.getChannel();
		
		while (fisChannel.read(buffer) != -1) {
			buffer.flip();
			writeChannel.write(buffer);
			buffer.clear();
		}
		fisChannel.close();
		fis.close();
		
		String path = writableFile.getFullPath();
		// Write more to the file in a separate request:
		writableFile = new AppEngineFile(path);
		// Lock the file because we intend to finalize it and
		// no one else should be able to edit it
		lock = true;
		writeChannel = fileService.openWriteChannel(writableFile, lock);
		// This time we write to the channel using standard Java
		writeChannel.write(ByteBuffer.wrap("And miles to go before I sleep."
				.getBytes()));

		// Now finalize
		writeChannel.closeFinally();
		return true;
	}
	
	public static boolean readFileToGoogleStorage(String bucketName, String fileName) throws FileNotFoundException, LockException, IOException {
		FileService fileService = FileServiceFactory.getFileService();
		// At this point, the file is visible in App Engine as:
		// "/gs/BUCKETNAME/FILENAME"
		// and to anybody on the Internet through Cloud Storage as:
		// (http://commondatastorage.googleapis.com/BUCKETNAME/FILENAME)
		// We can now read the file through the API:
		String filename = "/gs/" + bucketName + "/" + fileName;
		AppEngineFile readableFile = new AppEngineFile(filename);
		FileReadChannel readChannel = fileService.openReadChannel(readableFile,
				false);
		// Again, different standard Java ways of reading from the channel.
		BufferedReader reader = new BufferedReader(Channels.newReader(
				readChannel, "UTF8"));
		String line = reader.readLine();
		// line = "The woods are lovely, dark, and deep."
		readChannel.close();
		return false;
	}
}
